package cn.wolfcode.wolf2w.controller;

import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.domain.Travel;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.elasticsearch.domain.DestinationEs;
import cn.wolfcode.wolf2w.elasticsearch.domain.StrategyEs;
import cn.wolfcode.wolf2w.elasticsearch.domain.TravelEs;
import cn.wolfcode.wolf2w.elasticsearch.domain.UserInfoEs;
import cn.wolfcode.wolf2w.elasticsearch.query.SearchQueryObject;
import cn.wolfcode.wolf2w.elasticsearch.service.ISearchService;
import cn.wolfcode.wolf2w.elasticsearch.vo.SearchResultVO;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.service.ITravelService;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import cn.wolfcode.wolf2w.util.JsonResult;
import cn.wolfcode.wolf2w.util.ParamMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class SearchController {

    //mongodb服务
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private ITravelService travelService;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private ISearchService searchService;



    @RequestMapping("/q")
    public Object search(SearchQueryObject qo) throws UnsupportedEncodingException {

        // url 解码
        String kw = URLDecoder.decode(qo.getKeyword(), "UTF-8");
        qo.setKeyword(kw);

        if (qo.getType() == SearchQueryObject.TYPE_DEST) {
            return this.searchDest(qo);
        } else if(qo.getType() == SearchQueryObject.TYPE_STRATEGY) {
            return this.searchStrategy(qo);
        } else if(qo.getType() == SearchQueryObject.TYPE_TRAVEL) {
            return this.searchTravel(qo);
        } else if(qo.getType() == SearchQueryObject.TYPE_USER) {
            return this.searchUser(qo);
        } else {
            return this.searchAll(qo);
        }

    }


    // 搜索全部
    private Object searchAll(SearchQueryObject qo) {

        Page<UserInfo> us = this.createUserInfoPage(qo);
        Page<Travel> ts = this.createTravelPage(qo);
        Page<Strategy> sts = this.createStrategyPage(qo);
        Page<Destination> ds = this.createDestinationPage(qo);

        SearchResultVO vo = new SearchResultVO();
        vo.setUsers(us.getContent());
        vo.setTravels(ts.getContent());
        vo.setDests(ds.getContent());
        vo.setStrategys(sts.getContent());
        vo.setTotal(us.getTotalElements() + ts.getTotalElements() + ds.getTotalElements() + sts.getTotalElements());

        // 返回格式
        ParamMap map = ParamMap.newInstance();
        map.put("result", vo).put("qo", qo);

        return JsonResult.success(map);
    }

    // 搜索用户
    private Object searchUser(SearchQueryObject qo) {
        // 攻略全文搜搜 高亮显示
        Page<UserInfo> page = this.createUserInfoPage(qo);

        // 返回格式
        ParamMap map = ParamMap.newInstance();
        map.put("page", page).put("qo", qo);

        return JsonResult.success(map);
    }

    // 搜索游记
    private Object searchTravel(SearchQueryObject qo) {
        // 攻略全文搜搜 高亮显示
        Page<Travel> page = this.createTravelPage(qo);

        // 返回格式
        ParamMap map = ParamMap.newInstance();
        map.put("page", page).put("qo", qo);

        return JsonResult.success(map);
    }

    // 所有攻略
    private Object searchStrategy(SearchQueryObject qo) {

        // 攻略全文搜搜 高亮显示
        Page<Strategy> page = this.createStrategyPage(qo);

        // 返回格式
        ParamMap map = ParamMap.newInstance();
        map.put("page", page).put("qo", qo);

        return JsonResult.success(map);
    }

    // 查询所有目的地
    private Object searchDest(SearchQueryObject qo) {

        // 查询keyword对应的目的地是否存在
        Destination dest = destinationService.queryByName(qo.getKeyword());

        // 存在 查询所有攻略 游记 用户
        SearchResultVO searchResultVO = new SearchResultVO();
        if (dest != null) {
            List<Strategy> sts = strategyService.queryByDestId(dest.getId());
            List<Travel> ts = travelService.queryByDestId(dest.getId());
            List<UserInfo> us = userInfoService.queryByCity(dest.getName());
            searchResultVO.setStrategys(sts);
            searchResultVO.setTravels(ts);
            searchResultVO.setUsers(us);
            searchResultVO.setTotal(sts.size() + ts.size() + us.size() + 0L);
        }

        // 返回格式
        ParamMap map = ParamMap.newInstance();
        map.put("result", searchResultVO).put("dest", dest).put("qo", qo);

        return JsonResult.success(map);
    }

    private Page<Strategy> createStrategyPage(SearchQueryObject qo) {
        return searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME, Strategy.class, qo, "title", "subTitle", "summary");
    }

    private Page<UserInfo> createUserInfoPage(SearchQueryObject qo) {
        return searchService.searchWithHighlight(UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME, UserInfo.class, qo, "city", "info", "nickname");
    }

    private Page<Travel> createTravelPage(SearchQueryObject qo) {
        return searchService.searchWithHighlight(TravelEs.INDEX_NAME, TravelEs.TYPE_NAME, Travel.class, qo, "title", "summary");
    }

    private Page<Destination> createDestinationPage(SearchQueryObject qo) {
        return searchService.searchWithHighlight(DestinationEs.INDEX_NAME, DestinationEs.TYPE_NAME, Destination.class, qo, "name", "info");
    }


}
